#ifndef SOBJC_TYPE_H
#define SOBJC_TYPE_H

#include <sobjc-commons/port.h>
#include <sobjc-commons/str_list.h>
#include "class.h"
#include "node.h"
#include "scope.h"

#define OBJC_CTYPE_CHAR_CODE            'c'
#define OBJC_CTYPE_UCHAR_CODE           'C'
#define OBJC_CTYPE_SHORT_CODE           's'
#define OBJC_CTYPE_USHORT_CODE          'S'
#define OBJC_CTYPE_INT_CODE             'i'
#define OBJC_CTYPE_UINT_CODE            'I'
#define OBJC_CTYPE_LONG_CODE            'l'
#define OBJC_CTYPE_ULONG_CODE           'L'
#define OBJC_CTYPE_LONGLONG_CODE        'q'
#define OBJC_CTYPE_ULONGLONG_CODE       'Q'
#define OBJC_CTYPE_FLOAT_CODE           'f'
#define OBJC_CTYPE_DOUBLE_CODE          'd'
#define OBJC_CTYPE_VOID_CODE            'v'
#define OBJC_CTYPE_ID_CODE              '@'
#define OBJC_CTYPE_CLASS_CODE           '#'
#define OBJC_CTYPE_SEL_CODE             ':'
#define OBJC_CTYPE_SELF_CODE            '$'
#define OBJC_CTYPE_SUPER_CODE           '!'
#define OBJC_CTYPE_NIL_CODE             '0'
#define OBJC_CTYPE_GENERIC_PTR_CODE     'p'
#define OBJC_CTYPE_INSTANCE_CODE        '~'
#define OBJC_CTYPE_XSELF_CODE           '?'

#define OBJC_CTYPE_UNSIGNED_CODE        'u'
#define OBJC_CTYPE_CONST_CODE           'r'
#define OBJC_CTYPE_IN_CODE              'n'
#define OBJC_CTYPE_INOUT_CODE           'N'
#define OBJC_CTYPE_OUT_CODE             'o'
#define OBJC_CTYPE_BYCOPY_CODE          'O'
#define OBJC_CTYPE_BYREF_CODE           'R'
#define OBJC_CTYPE_ONEWAY_CODE          'V'

#define OBJC_CTYPE_PTR_CODE             '^'
#define OBJC_CTYPE_BITFIELD_CODE        'b'
#define OBJC_CTYPE_ARRAY_CODE           '+'
#define OBJC_CTYPE_STRUCT_BEGIN_CODE    '{'
#define OBJC_CTYPE_STRUCT_END_CODE      '}'
#define OBJC_CTYPE_UNION_BEGIN_CODE     '('
#define OBJC_CTYPE_UNION_END_CODE       ')'
#define OBJC_CTYPE_ENUM_BEGIN_CODE      '`'
#define OBJC_CTYPE_ENUM_END_CODE        '\''
#define OBJC_CTYPE_FUNC_BEGIN_CODE      '<'
#define OBJC_CTYPE_FUNC_END_CODE        '>'
#define OBJC_CTYPE_ELLIPSIS_CODE        '*'

#define OBJC_CTYPE_SU_NAME_SEP_CODE     '='
#define OBJC_CTYPE_MEM_NAME_SEP_CODE    '.'
#define OBJC_CTYPE_TERM_CODE            ';'

typedef struct objc_ctype_info *objc_ctype_info_t;

struct objc_ctype_info {
  char *name;
  objc_class_t cls;
  objc_str_list_t prtcs;
  BOOL is_declared;
  BOOL is_inst;
  BOOL is_id;
  BOOL is_super;
};

char *objc_ctype_from_decl(objc_scope_t, objc_node_t, objc_node_t);
char *objc_ctype_from_expr(objc_scope_t, objc_node_t);
char *objc_ctype_apply_func(const char *);
char *objc_ctype_get_arg_type(const char *, int);
BOOL objc_ctype_is_object(const char *);
objc_ctype_info_t objc_ctype_get_info(const char *, objc_class_t, BOOL);

#endif /* SOBJC_TYPE_H */


